package com.changan.enums;

import lombok.Getter;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.JDBCType;
import java.sql.Timestamp;

@Getter
public enum FieldType {
    LONG(0, "长整数", Long.class, "BIGINT", "BIGINT", "INT64", "BIGINT"),
    INTEGER(1, "整数", Integer.class, "INT", "INT", "INT32", "INT"),
    SMALLINT(7, "短整型", Short.class, "SMALLINT", "SMALLINT", "INT16", "SMALLINT"),
    STRING(2, "字符串", String.class, "STRING", "STRING", "STRING", "STRING"),
    DECIMAL(3, "浮点", BigDecimal.class, "DECIMAL", "DECIMAL", "DECIMAL", "DECIMAL"),
    //DECIMAL_WITH_PRECISION(3, "浮点", BigDecimal.class, "DECIMAL(38, 16)", "DECIMAL(38, 16)", "DECIMAL", "DECIMAL"),
    BOOLEAN(4, "布尔", Boolean.class, "BOOLEAN", "BOOLEAN", "BOOL", "BOOLEAN"),
    //DATE(5, "日期", Date.class, "TIMESTAMP", "UNIXTIME_MICROS", "TIMESTAMP"),
    DATE(5, "日期", Date.class, "DATE", "DATE", "UNIXTIME_MICROS", "TIMESTAMP"),
    TIMESTAMP(6, "时间戳", Timestamp.class, "TIMESTAMP", "TIMESTAMP", "UNIXTIME_MICROS", "TIMESTAMP"),
    DOUBLE(8, "双精度浮点型", Double.class, "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE"),
    BIT(9, "二进制", Byte.class, "BYTES", "STRING", "BINARY", "BINARY"),
    FLOAT(10, "双精度浮点型", Float.class, "FLOAT", "FLOAT", "FLOAT", "FLOAT");

    private Integer id;
    private String description;
    private Class clazz;
    private String flinkType;
    private String starrocksType;
    private String kuduType;
    private String hiveType;

    FieldType(Integer id, String description, Class clazz, String flinkType, String starrocksType, String kuduType, String hiveType) {
        this.id = id;
        this.description = description;
        this.clazz = clazz;
        this.flinkType = flinkType;
        this.starrocksType = starrocksType;
        this.kuduType = kuduType;
        this.hiveType = hiveType;
    }

    public static FieldType fromSimpleJdbcTypeName(String simpleName) {
        FieldType value = null;
        switch (simpleName.toUpperCase()) {
            case "LONGNVARCHAR":
            case "LONGVARCHAR":
            case "CHAR":
            case "VARCHAR":
            case "NCHAR":
            case "NVARCHAR":
            case "TEXT":
                value = STRING;
                break;
            case "TIME":
                value = TIMESTAMP;
                break;
            case "TINYINT":
                value = INTEGER;
                break;
            case "BOOL":
            case "BOOLEAN":
                value = BOOLEAN;
                break;
            case "SMALLINT":
                value = SMALLINT;
                break;
            case "INT":
            case "INTEGER":
                value = INTEGER;
                break;
            case "BIGINT":
            case "MEDIUMINT":
                value = LONG;
                break;
            case "DECIMAL":
                value = DECIMAL;
                break;
            case "FLOAT":
                value = FLOAT;
                break;
            case "DOUBLE":
                value = DOUBLE;
                break;
            case "DATE":
            case "YEAR":
                value = DATE;
                break;
            case "TIMESTAMP":
            case "DATETIME":
            case "TIMESTAMP_WITH_TIMEZONE":
                value = TIMESTAMP;
                break;
            case "CLOB":
            case "LONGVARBINARY":
            case "VARBINARY":
            case "BLOB":
            case "BINARY":
            case "BIT":
                value = ("BIT".equalsIgnoreCase(simpleName.toUpperCase())) ? BOOLEAN : STRING;
                break;
            case "DATALINK":
            case "STRUCT":
            case "DISTINCT":
            case "REF":
            case "SQLXML":
            case "JAVA_OBJECT":
            case "OTHER":
            case "ARRAY":
            case "ROWID":
            case "NULL":
            default:
                value = STRING;
                break;
        }

        return value;
    }

    public static FieldType convertTypeByJDBCType(JDBCType jdbcType, Integer typeLength) {
        FieldType value = null;
        switch (jdbcType) {
            case LONGNVARCHAR:
            case LONGVARCHAR:
            case CHAR:
            case VARCHAR:
            case NCHAR:
            case NVARCHAR:
            case TIME:
                value = STRING;
                break;
            case TINYINT:
                value = INTEGER;
                break;
            case BOOLEAN:
                value = BOOLEAN;
                break;
            case SMALLINT:
                value = SMALLINT;
                break;
            case INTEGER:
                value = INTEGER;
                break;
            case BIGINT:
                value = LONG;
                break;
            case DECIMAL:
                value = DECIMAL;
                break;
            case FLOAT:
                value = FLOAT;
                break;
            case DOUBLE:
                value = DOUBLE;
                break;
            case DATE:
                value = DATE;
                break;
            case TIMESTAMP:
            case TIMESTAMP_WITH_TIMEZONE:
                value = TIMESTAMP;
                break;
            case CLOB:
            case LONGVARBINARY:
            case VARBINARY:
            case BLOB:
            case BINARY:
            case BIT:
                value = ("BIT".equalsIgnoreCase(jdbcType.getName()) && typeLength == 1) ? BOOLEAN : BIT;
                break;
            case DATALINK:
            case STRUCT:
            case DISTINCT:
            case REF:
            case SQLXML:
            case JAVA_OBJECT:
            case OTHER:
            case ARRAY:
            case ROWID:
            case NULL:
            default:
                value = STRING;
                break;
        }

        return value;
    }
}
